<template>
  <ContentWrap>
    <!-- 人脸识别测试 -->
    <el-card class="box-card" shadow="never">
      <template #header>
        <div class="card-header">
          <el-icon>
            <Camera />
          </el-icon>
          <span>人脸识别测试</span>
        </div>
      </template>

      <!-- 实名认证功能区域 -->
      <div class="function-selection">
        <div class="welcome-section">
          <h2>🔐 实名认证系统</h2>
          <p class="welcome-desc">请选择您希望使用的实名认证方式，我们提供人脸注册和人脸搜索两种便捷的认证方式</p>
        </div>

        <!-- 当前用户信息 -->
        <div v-if="isUserLoggedIn" class="current-user-info">
          <div class="user-card">
            <el-avatar :size="50" :src="currentUser.avatar" :icon="User" class="user-avatar" />
            <div class="user-details">
              <div class="user-name">{{ currentUser.nickname || '未设置昵称' }}</div>
              <div class="user-id">ID: {{ currentUser.id }}</div>
            </div>
            <el-tag type="success" size="small">
              <el-icon>
                <View />
              </el-icon>
              已登录
            </el-tag>
          </div>
        </div>
        <div v-else class="login-warning">
          <el-alert title="请先登录" description="使用实名认证功能前，请先登录您的账户" type="warning" :closable="false" show-icon />
        </div>

        <!-- 功能选择卡片 -->
        <div class="function-cards">
          <div class="function-card register-card" @click="openRegisterModal" :class="{ disabled: !isUserLoggedIn }">
            <div class="card-icon">
              <el-icon size="48">
                <User />
              </el-icon>
            </div>
            <div class="card-content">
              <h3>👤 人脸注册</h3>
              <p>通过摄像头进行实名认证注册</p>
              <ul class="feature-list">
                <li>活体检测技术</li>
                <li>自动人脸注册</li>
                <li>安全身份绑定</li>
              </ul>
            </div>
            <div class="card-action">
              <el-button type="primary" :disabled="!isUserLoggedIn" @click="openRegisterModal">
                开始人脸注册
                <el-icon>
                  <ArrowRight />
                </el-icon>
              </el-button>
            </div>
          </div>

          <div class="function-card search-card" @click="openSearchModal" :class="{ disabled: !isUserLoggedIn }">
            <div class="card-icon">
              <el-icon size="48">
                <Search />
              </el-icon>
            </div>
            <div class="card-content">
              <h3>🔍 人脸搜索</h3>
              <p>通过摄像头搜索已注册用户</p>
              <ul class="feature-list">
                <li>实时人脸识别</li>
                <li>快速身份匹配</li>
                <li>高精度验证</li>
              </ul>
            </div>
            <div class="card-action">
              <el-button type="success" :disabled="!isUserLoggedIn" @click="openSearchModal">
                开始人脸搜索
                <el-icon>
                  <ArrowRight />
                </el-icon>
              </el-button>
            </div>
          </div>
        </div>
      </div>
    </el-card>

    <!-- 人脸注册弹窗 -->
    <FaceRegisterModal v-model="registerModalVisible" :config-list="configList" :config-loading="configLoading"
      @success="handleRecognizeSuccess" />

    <!-- 人脸搜索弹窗 -->
    <FaceSearchModal v-model="searchModalVisible" :config-list="configList" :config-loading="configLoading"
      @success="handleRecognizeSuccess" />

    <!-- 识别记录模块已删除 -->
  </ContentWrap>

  <!-- 记录详情弹窗已删除 -->
</template>

<script setup lang="ts">
import {
  UploadFilled,
  Camera,
  Search,
  VideoCamera,
  Close,
  User,
  ArrowRight
} from '@element-plus/icons-vue'
import { dateFormatter, formatDateTime } from '@/utils/formatTime'
import { getAccessToken } from '@/utils/auth'
import { useUserStore } from '@/store/modules/user'
import {
  getFaceConfigSimpleList,
  registerFace,
  searchFace,
  detectFace,
  registerFaceBase64,
  searchFaceBase64,
  detectFaceBase64,
  type FaceRegisterReqVO,
  type FaceSearchReqVO,
  type FaceDetectReqVO,
  type FaceRegisterRespVO,
  type FaceSearchRespVO,
  type FaceDetectRespVO
} from '@/api/infra/face'
import FaceRegisterModal from './components/FaceRegisterModal.vue'
import FaceSearchModal from './components/FaceSearchModal.vue'

/** 人脸识别测试 */
defineOptions({ name: 'InfraFaceTest' })

const message = useMessage() // 消息弹窗
const userStore = useUserStore() // 用户信息

// 上传相关
const uploadUrl = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/infra/file/upload'
const uploadHeaders = ref({
  Authorization: 'Bearer ' + getAccessToken()
})
const uploadRef = ref()
const fileList = ref([])

// 识别表单
const recognizeForm = ref({
  configId: undefined,
  imageUrl: '',
  userId: '',
  groupId: ''
})

// 当前登录用户信息
const currentUser = computed(() => userStore.getUser)
const isUserLoggedIn = computed(() => userStore.getIsSetUser && currentUser.value.id > 0)
const recognizing = ref(false)
const recognizeResult = ref<FaceRegisterRespVO | FaceSearchRespVO | FaceDetectRespVO | null>(null)

// 配置列表
const configList = ref([])
const configLoading = ref(false)

// 弹窗控制
const registerModalVisible = ref(false)
const searchModalVisible = ref(false)

// 记录列表相关变量已删除

// 摄像头相关
const videoRef = ref()
const canvasRef = ref()
const cameraActive = ref(false)
const cameraLoading = ref(false)
const mediaStream = ref<MediaStream | null>(null)
const capturedImageBase64 = ref('')

// 计算属性
const canRecognize = computed(() => {
  return recognizeForm.value.configId && recognizeForm.value.imageUrl
})

// 打开弹窗方法
const openRegisterModal = () => {
  if (!isUserLoggedIn.value) {
    message.warning('请先登录后再进行人脸注册')
    return
  }
  registerModalVisible.value = true
}

const openSearchModal = () => {
  if (!isUserLoggedIn.value) {
    message.warning('请先登录后再进行人脸搜索')
    return
  }
  searchModalVisible.value = true
}

// 处理识别成功回调
const handleRecognizeSuccess = () => {
  // 识别成功处理（记录列表功能已删除）
}

/** 初始化 */
onMounted(() => {
  getConfigList()
  // 自动填充当前登录用户ID
  if (isUserLoggedIn.value) {
    recognizeForm.value.userId = currentUser.value.id.toString()
  }
})

// 监听用户登录状态变化
watch(isUserLoggedIn, (newVal) => {
  if (newVal) {
    recognizeForm.value.userId = currentUser.value.id.toString()
  } else {
    recognizeForm.value.userId = ''
  }
}, { immediate: true })

/** 获取配置列表 */
const getConfigList = async () => {
  try {
    configLoading.value = true
    const data = await getFaceConfigSimpleList()
    // get-enabled接口返回单个配置对象，需要转换为数组
    configList.value = data ? [data] : []
  } catch (error) {
    console.error('获取配置列表失败:', error)
    configList.value = []
  } finally {
    configLoading.value = false
  }
}

/** 上传成功 */
const handleUploadSuccess = (response: any) => {
  if (response.code === 0) {
    recognizeForm.value.imageUrl = response.data
    message.success('图片上传成功')
  } else {
    message.error(response.msg || '上传失败')
  }
}

/** 上传失败 */
const handleUploadError = () => {
  message.error('图片上传失败')
}

/** 上传前检查 */
const beforeUpload = (file: File) => {
  const isImage = file.type.startsWith('image/')
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isImage) {
    message.error('只能上传图片文件!')
    return false
  }
  if (!isLt10M) {
    message.error('图片大小不能超过 10MB!')
    return false
  }
  return true
}

/** 文件数量超出限制 */
const handleExceed = () => {
  message.warning('只能上传一张图片')
}

/** 人脸注册 */
const handleRegister = async () => {
  if (!recognizeForm.value.userId) {
    message.warning('人脸注册需要填写用户ID')
    return
  }

  try {
    recognizing.value = true
    const params: FaceRegisterReqVO = {
      configId: recognizeForm.value.configId!,
      imageUrl: recognizeForm.value.imageUrl,
      userId: recognizeForm.value.userId,
      groupId: recognizeForm.value.groupId || undefined
    }

    const result = await registerFace(params)
    recognizeResult.value = result

    if (result.success) {
      message.success('人脸注册成功')
    } else {
      message.error(result.errorMessage || '人脸注册失败')
    }
  } catch (error) {
    console.error('人脸注册失败:', error)
    message.error('人脸注册失败')
  } finally {
    recognizing.value = false
  }
}

/** 人脸搜索 */
const handleSearch = async () => {
  try {
    recognizing.value = true
    const params: FaceSearchReqVO = {
      configId: recognizeForm.value.configId!,
      imageUrl: recognizeForm.value.imageUrl,
      groupId: recognizeForm.value.groupId || undefined
    }

    const result = await searchFace(params)
    recognizeResult.value = result

    if (result.success) {
      message.success('人脸搜索完成')
    } else {
      message.error(result.errorMessage || '人脸搜索失败')
    }
  } catch (error) {
    console.error('人脸搜索失败:', error)
    message.error('人脸搜索失败')
  } finally {
    recognizing.value = false
  }
}

/** 人脸检测 */
const handleDetect = async () => {
  try {
    recognizing.value = true
    const params: FaceDetectReqVO = {
      configId: recognizeForm.value.configId!,
      imageUrl: recognizeForm.value.imageUrl
    }

    const result = await detectFace(params)
    recognizeResult.value = result

    if (result.success) {
      message.success('人脸检测完成')
    } else {
      message.error(result.errorMessage || '人脸检测失败')
    }
  } catch (error) {
    console.error('人脸检测失败:', error)
    message.error('人脸检测失败')
  } finally {
    recognizing.value = false
  }
}

// 记录列表相关方法已删除

/** 获取结果标题 */
const getResultTitle = () => {
  if (!recognizeResult.value) return ''

  if (recognizeResult.value.success) {
    return '识别成功'
  } else {
    return '识别失败'
  }
}

// 记录列表相关的标签和文本方法已删除

// ========== 摄像头相关方法 ==========

/** 开启摄像头 */
const startCamera = async () => {
  try {
    cameraLoading.value = true

    const stream = await navigator.mediaDevices.getUserMedia({
      video: {
        width: { ideal: 640 },
        height: { ideal: 480 },
        facingMode: 'user' // 前置摄像头
      },
      audio: false
    })

    mediaStream.value = stream

    if (videoRef.value) {
      videoRef.value.srcObject = stream
      cameraActive.value = true
      message.success('摄像头已开启')
    }
  } catch (error) {
    console.error('开启摄像头失败:', error)
    message.error('无法访问摄像头，请检查权限设置')
  } finally {
    cameraLoading.value = false
  }
}

/** 关闭摄像头 */
const stopCamera = (showMessage = false) => {
  if (mediaStream.value) {
    mediaStream.value.getTracks().forEach(track => track.stop())
    mediaStream.value = null
  }

  if (videoRef.value) {
    videoRef.value.srcObject = null
  }

  cameraActive.value = false
  capturedImageBase64.value = ''
  
  // 只有在明确指定显示消息时才显示
  if (showMessage) {
    message.success('摄像头已关闭')
  }
}

/** 拍照并转换为Base64 */
const capturePhoto = () => {
  if (!videoRef.value || !canvasRef.value) {
    message.error('摄像头未准备就绪')
    return
  }

  const video = videoRef.value
  const canvas = canvasRef.value
  const ctx = canvas.getContext('2d')

  // 设置canvas尺寸与video一致
  canvas.width = video.videoWidth
  canvas.height = video.videoHeight

  // 绘制当前视频帧到canvas
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height)

  // 转换为Base64
  const imageData = canvas.toDataURL('image/jpeg', 0.8)
  const base64Data = imageData.split(',')[1] // 去掉data:image/jpeg;base64,前缀

  capturedImageBase64.value = base64Data

  // 更新识别表单的图片数据
  recognizeForm.value.imageUrl = imageData

  message.success('拍照成功')
}

/** 使用Base64进行人脸注册 */
const handleRegisterBase64 = async () => {
  if (!capturedImageBase64.value) {
    message.warning('请先拍照获取图片')
    return
  }

  if (!recognizeForm.value.userId) {
    message.warning('人脸注册需要填写用户ID')
    return
  }

  try {
    recognizing.value = true
    const params = {
      configId: recognizeForm.value.configId!,
      image: capturedImageBase64.value,
      userId: recognizeForm.value.userId,
      groupId: recognizeForm.value.groupId || 'default'
    }

    const result = await registerFaceBase64(params)
    recognizeResult.value = result

    if (result.success) {
      message.success('人脸注册成功')
    } else {
      message.error(result.errorMessage || '人脸注册失败')
    }
  } catch (error) {
    console.error('人脸注册失败:', error)
    message.error('人脸注册失败')
  } finally {
    recognizing.value = false
  }
}

/** 使用Base64进行人脸搜索 */
const handleSearchBase64 = async () => {
  if (!capturedImageBase64.value) {
    message.warning('请先拍照获取图片')
    return
  }

  try {
    recognizing.value = true
    const params = {
      configId: recognizeForm.value.configId!,
      image: capturedImageBase64.value,
      groupId: recognizeForm.value.groupId || 'default',
      maxUserNum: 10
    }

    const result = await searchFaceBase64(params)
    recognizeResult.value = result

    if (result.success) {
      message.success('人脸搜索完成')
    } else {
      message.error(result.errorMessage || '人脸搜索失败')
    }
  } catch (error) {
    console.error('人脸搜索失败:', error)
    message.error('人脸搜索失败')
  } finally {
    recognizing.value = false
  }
}

/** 使用Base64进行人脸检测 */
const handleDetectBase64 = async () => {
  if (!capturedImageBase64.value) {
    message.warning('请先拍照获取图片')
    return
  }

  try {
    recognizing.value = true
    const params = {
      configId: recognizeForm.value.configId!,
      image: capturedImageBase64.value
    }

    const result = await detectFaceBase64(params)
    recognizeResult.value = result

    if (result.success) {
      message.success('人脸检测完成')
    } else {
      message.error(result.errorMessage || '人脸检测失败')
    }
  } catch (error) {
    console.error('人脸检测失败:', error)
    message.error('人脸检测失败')
  } finally {
    recognizing.value = false
  }
}

/** 组件卸载时关闭摄像头 */
onUnmounted(() => {
  stopCamera()
})
</script>

<style scoped>
/* 整体布局优化 */
.face-test-container {
  max-width: 1400px;
  margin: 0 auto;
  padding: 24px;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  min-height: 100vh;
}

/* 功能说明样式 */
.section-description {
  margin-bottom: 16px;
  padding: 12px 16px;
  background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%);
  border-radius: 8px;
  border-left: 4px solid #667eea;
}

.section-description p {
  margin: 0;
  color: #37474f;
  font-size: 14px;
  line-height: 1.5;
}

.operation-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.step {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
}

.group-description {
  margin-bottom: 12px;
  padding: 8px 12px;
  background: rgba(102, 126, 234, 0.1);
  border-radius: 6px;
  border: 1px solid rgba(102, 126, 234, 0.2);
}

.group-description p {
  margin: 0;
  color: #5a6c7d;
  font-size: 13px;
}

.form-tip {
  margin-top: 4px;
  color: #8a8e99;
  font-size: 12px;
  line-height: 1.4;
}

.placeholder-tip {
  font-size: 14px;
  margin-top: 8px;
  opacity: 0.8;
  color: #6c757d;
}

.button-tip {
  display: block;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.8);
  margin-top: 2px;
  font-weight: normal;
}

.card-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 20px 24px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-radius: 12px 12px 0 0;
  margin: -20px -20px 20px -20px;
}

.card-header .el-icon {
  font-size: 24px;
}

.card-header h3 {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
}

.header-actions {
  margin-left: auto;
}

/* 功能区域布局 */
.upload-section,
.config-section,
.action-section,
.result-section {
  margin-bottom: 32px;
  padding: 24px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  border: 1px solid #e8eaed;
  transition: all 0.3s ease;
}

.upload-section:hover,
.config-section:hover,
.action-section:hover,
.result-section:hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

/* 标题层次优化 */
.upload-section h4,
.config-section h4,
.action-section h4,
.result-section h4 {
  margin: -24px -24px 20px -24px;
  padding: 16px 24px;
  color: #2c3e50;
  font-weight: 600;
  font-size: 16px;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-bottom: 2px solid #e8eaed;
  border-radius: 12px 12px 0 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.upload-section h4::before {
  content: "📁";
  font-size: 18px;
}

.config-section h4::before {
  content: "⚙️";
  font-size: 18px;
}

.action-section h4::before {
  content: "🎯";
  font-size: 18px;
}

.result-section h4::before {
  content: "📊";
  font-size: 18px;
}

/* 上传区域优化 */
.upload-demo {
  width: 100%;
}

.upload-tip {
  margin-top: 12px;
  text-align: center;
  color: #606266;
  font-size: 14px;
}

/* 表单优化 */
.el-form {
  background: #fafbfc;
  padding: 20px;
  border-radius: 8px;
  border: 1px solid #e8eaed;
  transition: all 0.3s ease;
}

.el-form:hover {
  border-color: #667eea;
  box-shadow: 0 2px 8px rgba(102, 126, 234, 0.1);
}

.el-form-item {
  margin-bottom: 20px;
  transition: all 0.3s ease;
}

.el-form-item__label {
  font-weight: 500;
  color: #2c3e50;
  transition: color 0.3s ease;
}

.el-form-item.is-required .el-form-item__label::before {
  color: #f56565;
  margin-right: 4px;
}

/* 输入框优化 */
.el-input__wrapper {
  border-radius: 8px;
  transition: all 0.3s ease;
  border: 2px solid #e8eaed;
}

.el-input__wrapper:hover {
  border-color: #667eea;
  box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1);
}

.el-input__wrapper.is-focus {
  border-color: #667eea;
  box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
}

.el-input__inner {
  color: #2c3e50;
  font-weight: 500;
}

.el-input__inner::placeholder {
  color: #8a8e99;
  font-weight: normal;
}

/* 选择器优化 */
.el-select {
  width: 100%;
}

.el-select .el-input__wrapper {
  border-radius: 8px;
}

.el-select .el-input__wrapper:hover {
  border-color: #667eea;
}

.el-select .el-input__wrapper.is-focus {
  border-color: #667eea;
  box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
}

/* 上传组件优化 */
.el-upload-dragger {
  border: 2px dashed #d1d5db;
  border-radius: 12px;
  background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%);
  transition: all 0.3s ease;
}

.el-upload-dragger:hover {
  border-color: #667eea;
  background: linear-gradient(135deg, #f0f4ff 0%, #e0e7ff 100%);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(102, 126, 234, 0.15);
}

.el-upload-dragger.is-dragover {
  border-color: #48bb78;
  background: linear-gradient(135deg, #f0fff4 0%, #dcfce7 100%);
  transform: scale(1.02);
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .face-test-container {
    padding: 15px;
  }

  .action-buttons {
    grid-template-columns: 1fr;
    gap: 20px;
  }
}

@media (max-width: 768px) {
  .face-test-container {
    padding: 10px;
  }

  .card-header h3 {
    font-size: 20px;
  }

  .upload-section,
  .camera-section,
  .config-section {
    padding: 15px;
  }

  .camera-container {
    max-width: 100%;
    height: 250px;
  }

  .camera-video,
  .camera-canvas {
    max-height: 200px;
  }

  .camera-controls {
    flex-direction: column;
    gap: 10px;
  }

  .camera-controls .el-button {
    width: 100%;
  }

  .action-buttons {
    grid-template-columns: 1fr;
    gap: 15px;
  }

  .button-group {
    padding: 15px;
  }

  .button-group .el-button {
    width: 100%;
    margin-bottom: 10px;
  }

  .el-form {
    padding: 15px;
  }

  .record-table {
    font-size: 12px;
  }

  .table-image {
    width: 40px;
    height: 40px;
  }
}

@media (max-width: 480px) {
  .face-test-container {
    padding: 8px;
  }

  .card-header {
    padding: 15px;
  }

  .card-header h3 {
    font-size: 18px;
  }

  .upload-section,
  .camera-section,
  .config-section {
    padding: 12px;
  }

  .camera-container {
    height: 200px;
  }

  .camera-video,
  .camera-canvas {
    max-height: 150px;
  }

  .button-group h5 {
    font-size: 14px;
  }

  .el-button {
    font-size: 12px;
    padding: 8px 15px;
  }

  .section-description {
    font-size: 12px;
  }

  .operation-steps {
    font-size: 11px;
  }

  .group-description {
    font-size: 11px;
  }

  .button-tip {
    font-size: 10px;
  }
}

/* 触摸设备优化 */
@media (hover: none) and (pointer: coarse) {
  .el-button {
    min-height: 44px;
    font-size: 14px;
  }

  .camera-controls .el-button {
    min-height: 48px;
    font-size: 16px;
  }

  .el-input__inner {
    min-height: 44px;
    font-size: 16px;
  }

  .el-select .el-input__inner {
    min-height: 44px;
  }

  .table-image {
    width: 50px;
    height: 50px;
  }
}

/* 操作按钮区域优化 */
.action-buttons {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.button-group {
  padding: 20px;
  border: 2px solid #e8eaed;
  border-radius: 12px;
  background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.button-group::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
}

.button-group:hover {
  border-color: #667eea;
  box-shadow: 0 4px 16px rgba(102, 126, 234, 0.15);
  transform: translateY(-2px);
}

.button-group h5 {
  margin: 0 0 18px 0;
  color: #2c3e50;
  font-size: 15px;
  font-weight: 600;
  border-bottom: 2px solid #e8eaed;
  padding-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.button-group h5::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.button-group .el-button {
  margin-right: 12px;
  margin-bottom: 12px;
  min-width: 120px;
  height: 40px;
  border-radius: 20px;
  font-weight: 500;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.button-group .el-button:hover:not(.is-disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.button-group .el-button.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.button-group .el-button.is-loading {
  position: relative;
}

.button-group .el-button.is-loading::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
  animation: loading-shimmer 1.5s infinite;
}

@keyframes loading-shimmer {
  0% {
    left: -100%;
  }

  100% {
    left: 100%;
  }
}

/* 按钮类型特定样式 */
.el-button--primary {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
}

.el-button--primary:hover:not(.is-disabled) {
  background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
}

.el-button--success {
  background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
  border: none;
}

.el-button--success:hover:not(.is-disabled) {
  background: linear-gradient(135deg, #38a169 0%, #2f855a 100%);
}

.el-button--warning {
  background: linear-gradient(135deg, #ed8936 0%, #dd6b20 100%);
  border: none;
}

.el-button--warning:hover:not(.is-disabled) {
  background: linear-gradient(135deg, #dd6b20 0%, #c05621 100%);
}

.el-button--danger {
  background: linear-gradient(135deg, #f56565 0%, #e53e3e 100%);
  border: none;
}

.el-button--danger:hover:not(.is-disabled) {
  background: linear-gradient(135deg, #e53e3e 0%, #c53030 100%);
}

/* 结果展示区域优化 */
.result-alert {
  margin-bottom: 20px;
  border-radius: 8px;
  border: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.success-result {
  margin-top: 20px;
}

.success-result .el-descriptions {
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.error-result {
  margin-top: 20px;
}

.no-result {
  text-align: center;
  padding: 60px 0;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-radius: 12px;
  border: 2px dashed #dee2e6;
}

/* 记录表格优化 */
.record-card {
  margin-top: 32px;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  border: 1px solid #e8eaed;
}

.record-card .card-header {
  background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
}

.record-table {
  margin-bottom: 20px;
}

.record-table .el-table {
  border-radius: 8px;
  overflow: hidden;
}

.record-table .el-table th {
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  color: #2c3e50;
  font-weight: 600;
  border-bottom: 2px solid #dee2e6;
}

.record-table .el-table td {
  border-bottom: 1px solid #f1f3f4;
}

.record-table .el-table tr:hover td {
  background-color: #f8f9ff;
}

.image-cell {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 8px;
}

.table-image {
  width: 64px;
  height: 64px;
  border-radius: 8px;
  object-fit: cover;
  border: 2px solid #e8eaed;
  transition: all 0.3s ease;
}

.table-image:hover {
  transform: scale(1.1);
  border-color: #667eea;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}

.pagination-container {
  display: flex;
  justify-content: center;
  margin-top: 24px;
  padding: 20px;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-radius: 12px;
}

/* 详情弹窗优化 */
.detail-dialog .detail-content {
  padding: 0;
}

.detail-image-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 400px;
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
  border-radius: 12px;
  margin: 20px;
}

.detail-image {
  max-width: 100%;
  max-height: 100%;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

.error-section {
  margin-top: 20px;
}

/* 摄像头相关样式 */
.camera-section {
  margin-bottom: 24px;
}

.camera-section h4 {
  margin-bottom: 16px;
  color: #303133;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.camera-container {
  border: 2px dashed #dcdfe6;
  border-radius: 12px;
  padding: 20px;
  background-color: #fafafa;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.camera-container:hover {
  border-color: #409eff;
  background-color: #f0f9ff;
}

.camera-preview {
  position: relative;
  width: 100%;
  height: 300px;
  border-radius: 8px;
  overflow: hidden;
  background-color: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.camera-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
}

.camera-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.camera-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #909399;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  background-size: 200% 200%;
  animation: gradientShift 3s ease infinite;
}

@keyframes gradientShift {
  0% {
    background-position: 0% 50%;
  }

  50% {
    background-position: 100% 50%;
  }

  100% {
    background-position: 0% 50%;
  }
}

.camera-placeholder .el-icon {
  color: #ffffff;
  margin-bottom: 12px;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}

.camera-placeholder p {
  color: #ffffff;
  font-size: 16px;
  font-weight: 500;
  margin: 0;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.camera-controls {
  margin-top: 16px;
  display: flex;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}

.camera-controls .el-button {
  min-width: 120px;
  height: 40px;
  font-weight: 500;
  border-radius: 20px;
  transition: all 0.3s ease;
}

.camera-controls .el-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.camera-controls .el-button .el-icon {
  margin-right: 6px;
}

/* 摄像头状态指示器 */
.camera-status {
  position: absolute;
  top: 12px;
  right: 12px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  border-radius: 16px;
  font-size: 12px;
  font-weight: 500;
}

.camera-status.active {
  background: rgba(67, 160, 71, 0.9);
}

.camera-status.inactive {
  background: rgba(158, 158, 158, 0.9);
}

.camera-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% {
    opacity: 1;
  }

  50% {
    opacity: 0.5;
  }

  100% {
    opacity: 1;
  }
}

/* 用户信息区域样式 */
.user-info-section {
  margin-bottom: 24px;
}

.user-info-section h4 {
  margin-bottom: 16px;
  color: #303133;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.user-info-card {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 16px;
  box-shadow: 0 8px 24px rgba(102, 126, 234, 0.2);
  color: white;
  transition: all 0.3s ease;
}

.user-info-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 32px rgba(102, 126, 234, 0.3);
}

.user-avatar {
  flex-shrink: 0;
}

.user-avatar-img {
  border: 3px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.user-details {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.user-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  font-weight: 600;
  color: white;
}

.user-name .el-icon {
  color: rgba(255, 255, 255, 0.8);
}

.user-id {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
}

.user-id .label {
  color: rgba(255, 255, 255, 0.8);
  font-weight: 500;
}

.user-id .el-tag {
  background: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: white;
  font-weight: 500;
}

.user-status {
  display: flex;
  align-items: center;
}

.user-status .el-tag {
  background: rgba(76, 175, 80, 0.2);
  border: 1px solid rgba(76, 175, 80, 0.4);
  color: #4caf50;
  font-weight: 500;
}

.user-status .el-tag .el-icon {
  margin-right: 4px;
}

.user-info-empty {
  padding: 16px;
}

.user-info-empty .el-alert {
  border-radius: 12px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .user-info-card {
    flex-direction: column;
    text-align: center;
    gap: 16px;
  }

  .user-details {
    align-items: center;
  }
}
</style>